package com.yzkj.framework.core.util.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.yzkj.framework.beans.exception.YzkjException;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Jwt AES 加解密工具类
 *
 * @author Helon
 */
public class JwtHelper {

    // 设置过期时间
    private static final long EXPIRE_DATE = 60 * 60 * 24 * 7 * 1000;

    // token秘钥
    private static final String TOKEN_SECRET = "yzkj-token-2021-1024";


    /**
     * 生产Token
     */
    public static String create(Map<String, String> claims) {
        try {
            //过期时间
            Date date = new Date(System.currentTimeMillis() + EXPIRE_DATE);
            //秘钥及加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            //设置头部信息
            Map<String, Object> header = new HashMap<>();
            header.put("typ", "JWT");
            header.put("alg", "HS256");
            //携带用户信息，生成签名

            JWTCreator.Builder jwtBuilder = JWT.create().withHeader(header);
            claims.forEach(jwtBuilder::withClaim);
            return jwtBuilder.sign(algorithm);
        } catch (Exception e) {
            throw YzkjException.of("生成token时出现错误！");
        }
    }

    /**
     * 验证token，通过返回所有参数
     *
     * @param token token字符串
     **/
    public static Map<String, Claim> verify(String token) {
        if (StringUtils.isEmpty(token)) {
            throw YzkjException.of("token为空！");
        }
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return jwt.getClaims();
        } catch (Exception e) {
            throw YzkjException.of("token验证失败！");
        }
    }

    /**
     * 验证token，通过返回指定Claim
     *
     * @param token token字符串
     **/
    public static Claim verify(String token, String claim) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return jwt.getClaim(claim);
        } catch (Exception e) {
            throw YzkjException.of("token验证失败！");
        }
    }
}
